test: assert cat_tools' schema(s) are never on search_path - #76
test: assert cat_tools' schema(s) are never on search_path#76jnasbyupgrade wants to merge 5 commits into
Conversation
… search_path cat_tools' control file pins schema = 'cat_tools' with relocatable = false -- it can never be installed into a user-chosen schema, so there was never a "which schema" question to test. The real, narrower risk is that some cat_tools view/function could call another cat_tools object unqualified, relying on search_path to resolve it -- which would keep working by accident in any session that happens to have 'cat_tools' searchable, and only break for a real caller who doesn't. Verified empirically before adding this: pgxntool's own tap_setup.sql (\i'd by every test/sql/*.sql file via test/setup.sql) already sets `search_path = tap, public` -- cat_tools' schemas are already never on it today, for every test in the suite, with no toggle needed. This assertion just makes that fact explicit and self-documenting instead of true by accident of the shared baseline, so a future change to it fails loudly instead of silently widening what "passing" means. current_schemas(false) is Postgres's own unqualified-name search list, so checking cat_tools/_cat_tools are absent from it is a direct proof, not a proxy for one (confirmed the check fires: manually SET search_path to include 'cat_tools' and confirmed the RAISE EXCEPTION triggers with the expected message). Always-on, no GUC, no variable, no separate test target -- this is not a toggleable dimension, just a permanent fact this suite now checks.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Claude finished @jnasbyupgrade's task in 1m 56s —— View job Code review
Summary: Adds a Checks performed:
No issues found. Checked for bugs and CLAUDE.md compliance. |
…ile end Replace test/setup.sql's DO-block assertion (checked once, at the START of every test file) with test/finish.sql, a real, plan()-counted pgTAP test \i'd right before finish() at the END of every test/sql/*.sql file. This is strictly stronger: a start-only check cannot see a test that mutates search_path partway through a file. Confirmed empirically that each test/sql file runs as its own psql connection wrapped in a transaction that never commits (rolled back when the connection closes), so a plain SET search_path already cannot leak into a LATER file regardless of when it's checked -- the real gap a start-only check leaves open is a mutation that stays in effect for the rest of THAT SAME file's own tests, which checking again at the end now catches. Not foolproof: a test that mutates search_path and then restores it before this check would still slip through. Making it a counted pgTAP test (not a DO block) means a new test file author bumping their own plan() count has to notice this test exists -- a natural reminder not to add a search_path-dependent test without thinking about it. Every test/sql/*.sql file's plan() count is bumped by 1 and expected output regenerated via `make results` accordingly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… second \i Each test/sql/*.sql file now has exactly one finish-side \i (test/finish.sql), mirroring how they already have exactly one setup-side \i (test/setup.sql, which itself \i's test/pgxntool/setup.sql as its first line). test/finish.sql runs the search_path assertion and then \i's test/pgxntool/finish.sql as its last line, rather than every test file calling both directly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Claude finished @jnasbyupgrade's task in 1m 39s —— View job Code review
Summary: Replaces the earlier Checks performed:
No issues found. |
The previous comment recounted the empirical investigation that justified this design (psql-connection-per-file, transaction rollback semantics) -- that belongs in the PR description, not as a permanent code comment. Keep only the conclusion: what this asserts, why file-end (not just setup), the one caveat, and the plan()-bump reminder. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Claude finished @jnasbyupgrade's task in 2m 34s —— View job Code review
Summary: Since the last review pass (which covered through Finding
Everything else checked and unchanged from prior passes: the shortened comment's content is accurate and still explains the "why file-end" rationale and the mutate-then-restore caveat without recounting the empirical investigation history (matches CLAUDE.md's Bug Fixes guidance — no novels, no unnecessary history). Logic of the No other issues found. |
…bump aside Convert the trailing two-line -- comment to a /* */ block comment per CLAUDE.md's Code Style section (never -- for multi-line explanations). Also drop the "bump that file's plan() by one" clause from the main comment -- anyone writing a test already knows to keep plan() in sync with its assertions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Claude finished @jnasbyupgrade's task in 58s —— View job Code review
Summary: Since the last review pass (which covered through
Checks performed:
No issues found. |
Add a permanent, real pgTAP test that asserts
cat_tools/_cat_toolsare never part of the resolvedsearch_pathduring testing.test/finish.sqlis\i'd by everytest/sql/*.sqlfile right beforefinish(), checkingcurrent_schemas(false)-- Postgres's own unqualified-name resolution list. It's a real,plan()-counted assertion rather than a silentDOblock, so a future test file bumping its ownplan()count has to notice it exists.Checking at the end of each file, not just at setup, is what matters: pgxntool's own
tap_setup.sqlalready keepssearch_pathclean at the start of every test file, so a start-only check can only prove that much -- it can't see a test that mutatessearch_pathpartway through and leaves it that way. Checking again right beforefinish()catches that case too. One caveat: a test that mutatessearch_pathand then restores it before this check runs would still slip through.Test plan
make verify-resultspasses locally with the newtest/finish.sqlin place, andtest/expected/*.outregenerated viamake resultsSET search_path = cat_tools, tap, publicinto a scratch test file and confirmed only that file'stest/finish.sqlcheck failed -- files run afterward were unaffected, confirming the per-file connection/rollback isolationmake lintclean